/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.worldscale.xp.wslib.im.jabber.impl;

import java.util.Enumeration;
import java.util.Vector;
import net.worldscale.xp.wslib.im.jabber.JabberID;
import net.worldscale.xp.wslib.im.jabber.JabberClient;
import net.worldscale.xp.wslib.im.jabber.JabberClient.PhaseListener;
import net.worldscale.xp.wslib.im.jabber.JabberClient.RosterManager;
import net.worldscale.xp.wslib.im.jabber.JabberClient.StreamListener;
import org.w3c.dom.Element;

/**
 *
 * @author Kun
 */
final class JabberEventRouter implements
        JabberClient.PhaseListener,
        JabberClient.RosterManager,
        JabberClient.StreamListener {

    private JabberClient.RosterManager mRosterMan;
    private final MyPhaseEventDispatcher mPhaseEventDisp;
    private final MyStreamEventDispatcher mStreamEventDisp;

    private static class MyPhaseEventDispatcher implements JabberClient.PhaseListener {

        private final Vector<JabberClient.PhaseListener> mV;

        public MyPhaseEventDispatcher() {
            mV = new Vector<JabberClient.PhaseListener>();
        }

        public void addListener(JabberClient.PhaseListener l) {
            if (l != null) {
                if (!mV.contains(l)) {
                    mV.addElement(l);
                }
            }
        }

        public void removeListener(JabberClient.PhaseListener l) {
            if (l != null) {
                mV.removeElement(l);
            }
        }

        public void onPhaseChanged(int oldPhase, int newPhase) {
            final Enumeration<JabberClient.PhaseListener> enu = mV.elements();
            for (; enu.hasMoreElements();) {
                try {
                    final JabberClient.PhaseListener l = enu.nextElement();
                    l.onPhaseChanged(oldPhase, newPhase);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static class MyStreamEventDispatcher implements JabberClient.StreamListener {

        private final Vector<JabberClient.StreamListener> mV;

        public MyStreamEventDispatcher() {
            mV = new Vector<JabberClient.StreamListener>();
        }

        public void addListener(JabberClient.StreamListener l) {
            if (l != null) {
                if (!mV.contains(l)) {
                    mV.addElement(l);
                }
            }
        }

        public void removeListener(JabberClient.StreamListener l) {
            if (l != null) {
                mV.removeElement(l);
            }
        }

        public void onStanza(Element stanza) {
            final Enumeration<JabberClient.StreamListener> enu = mV.elements();
            for (; enu.hasMoreElements();) {
                try {
                    final JabberClient.StreamListener l = enu.nextElement();
                    l.onStanza(stanza);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        public void onStreamClose() {
            final Enumeration<JabberClient.StreamListener> enu = mV.elements();
            for (; enu.hasMoreElements();) {
                try {
                    final JabberClient.StreamListener l = enu.nextElement();
                    l.onStreamClose();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        public void onStreamOpen() {
            final Enumeration<JabberClient.StreamListener> enu = mV.elements();
            for (; enu.hasMoreElements();) {
                try {
                    final JabberClient.StreamListener l = enu.nextElement();
                    l.onStreamOpen();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public JabberEventRouter() {
        mStreamEventDisp = new MyStreamEventDispatcher();
        mPhaseEventDisp = new MyPhaseEventDispatcher();
    }

    public void onPhaseChanged(int oldPhase, int newPhase) {
        this.mPhaseEventDisp.onPhaseChanged(oldPhase, newPhase);
    }

    public void saveRoster(JabberID owner, Element roster) {
        final RosterManager rm = this.mRosterMan;
        if (rm != null) {
            rm.saveRoster(owner, roster);
        }
    }

    public Element loadRoster(JabberID owner) {
        final RosterManager rm = this.mRosterMan;
        if (rm != null) {
            return rm.loadRoster(owner);
        } else {
            return null;
        }
    }

    public void onStreamOpen() {
        this.mStreamEventDisp.onStreamOpen();
    }

    public void onStreamClose() {
        this.mStreamEventDisp.onStreamClose();
    }

    public void onStanza(Element stanza) {
        this.mStreamEventDisp.onStanza(stanza);
    }

    public void setRosterManager(RosterManager rm) {
        this.mRosterMan = rm;
    }

    public void addPhaseListener(PhaseListener pl) {
        this.mPhaseEventDisp.addListener(pl);
    }

    public void addStreamListener(StreamListener sl) {
        this.mStreamEventDisp.addListener(sl);
    }

    public void removePhaseListener(PhaseListener pl) {
        this.mPhaseEventDisp.removeListener(pl);
    }

    public void removeStreamListener(StreamListener sl) {
        this.mStreamEventDisp.removeListener(sl);
    }
}
